<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>
FFmpegSource2 API Documentation
</title>
<link href="style.css" media="screen" rel="Stylesheet" type="text/css" />
</head>
<body>
<div class="maincontent">
<h1>FFmpegSource2 API Documentation</h1>
<p>
FFmpegSource2 (FFMS2) is a wrapper library around ffmpeg, plus some additional components to deal with file formats libavformat has (or used to have) problems with. It gives you a convenient way to say "open and decompress this media file for me, I don't care how you do it", without having to bother with the sometimes less than straightforward and less than perfectly documented ffmpeg internals. May be frame and/or sample accurate on good days. The library is written in C++, but the public API is C-friendly and it is possible to simply include and link directly with a pure C application.</p>

<p>The source is MIT licensed and can be obtained from the Google Code project SVN; see <a href="http://code.google.com/p/ffmpegsource/source/checkout">http://code.google.com/p/ffmpegsource/source/checkout</a>.
</p>


<h2>Limitations</h2>
<p>
FFMS2 does not mux or encode anything. FFMS2 does not give you fine control over codec internals. FFMS2 does not let you demux raw compressed data, you get it decompressed or not at all. FFMS2 does not provide you with a good solution for realtime playback, since it needs to index the input file before you can retreive frames or audio samples. FFMS2 does not currently handle things like subtitles, file attachments or chapters. FFMS2's video frame and audio sample retrieval functions are not threadsafe; you may only have one request going at a time.
</p>


<h2>Compilation</h2>
<p>FFMS2 has the following dependencies:</p>
<ul>
<li><b><a href="http://www.ffmpeg.org">ffmpeg</a></b> (no, really)
<ul><li>Revision <del>18378 (2009-04-08) or later</del> something very fucking recent (usually you should just use the latest SVN revision you can get to compile) is required. 0.5 is too old.</li>
<li><a href="http://gitorious.org/ffmpeg/ffmpeg-mt">ffmpeg-mt</a> with pthreads may be used instead of vanilla ffmpeg.</li>
<li>Needs to have libpostproc compiled in (pass <tt>--enable-gpl --enable-postproc</tt> to ffmpeg's ./configure).</li>
<li>If you're on Win32 you need to pass <tt>--enable-memalign-hack</tt> to ffmpeg's ./configure as well.</li>
<li>Further recommended configuration options: <tt>--disable-debug --disable-muxers --disable-encoders --disable-filters --disable-hwaccels --disable-network --disable-devices --enable-runtime-cpudetect</tt> (runtime cpudetect in particular is a good idea if you are planning on distributing the library; not disabling debug results in a gigantic dll).</li>
</ul>
</li>
<li><b><a href="http://www.zlib.net/">zlib</a></b></li>
</ul>
<p>
Compiling the library itself is fairly straightforward. For the basics, just add the <tt>include</tt> folder to your include paths and compile everything in <tt>src/core</tt>; everything else can be skipped. <tt>src/avisynth</tt> contains code for some Avisynth filters (optional and Windows-only); <tt>src/config</tt> is some (mostly autogenerated) configuration headers; <tt>src/index</tt> is a stand-alone indexing application (built separately and linked against the main FFMS2 library); and <tt>src/test</tt> is an (incomplete) automatic regression test tool (also built separately). Take a look in <tt>doc/compiling.txt</tt> in the source tree for further details.
</p>
<h3>Windows-specific compilation notes</h3>
<p>
If you're compiling the library on Windows, it is suggested that you use the Microsoft Visual Studio 2008 solution file from SVN. Any version of MSVC2008 should work for compiling it, including the free Express Edition (but if you use that you must undefine HAALISOURCE or find a copy of the ATL libraries). The project file in question assumes that you have compiled ffmpeg with MinGW (guides on how to do that are easy to find) and want to link FFMS2 with it statically (linking it dynamically is possible but not recommended since it usually leads to DLL hell). Add your mingw/include and mingw/lib folders to MSVC's respective global directory settings (Tools menu -&gt; Options -&gt; Projects and Solutions -&gt; VC++ Directories) and you should be good to go.
</p>
<p>
If you're using anything else, you're on your own. It's possible to build the library (but not the Avisynth plugin) using MinGW; this is also the only way to build a 64-bit version of FFMS2 at the moment. If you're rolling your own MSVC solution file, remember that you need to <tt>#define FFMS_EXPORTS</tt> somewhere when compiling the library. You may also <tt>#define HAALISOURCE</tt> if you want to make the library able to open MPEG TS/PS and OGM files using Haali's DirectShow splitter (if you do not define it, those files will be opened with libavformat instead, and that usually doesn't work out all that well). Note that if you do so, opening those files will fail unless the user has the <a href="http://haali.cs.msu.ru/mkv/">Haali Media Splitter</a> DirectShow filter installed. Both those defines are enabled by default in the solution file in SVN.
</p>


<h2>Quickstart guide for impatient people</h2>
<p>
If you don't want to know anything about anything and just want to open some video with FFMS2 in the absolutely simplest possible manner, without selective indexing, progress reporting, saved index files, keyframe or timecode reading or anything like that, here's how to do it with the absolutely bare minimum of code.</p>

<pre>
#include &lt;ffms.h&gt;
#ifdef _WIN32
#include &lt;objbase.h&gt;
#endif

int main (...) {
	/* If you are on Windows you should first initialize COM, or all MPEG-TS/PS and OGM
	files may return an error when you try to open them (if the library was built
	with HAALISOURCE defined). All other formats will work normally. */
#ifdef _WIN32
	bool com_inited = false;
	HRESULT res = CoInitializeEx(NULL, COINIT_MULTITHREADED);
	if (SUCCEEDED(res)) 
		com_inited = true;
	else if (res != RPC_E_CHANGED_MODE) {
		/* com initialization failed, handle error */
	}
#endif

	/* Initialize the library itself.
	You'll probably want to do the CPU caps detection automatically,
	or pass 0 if you don't care. */
	FFMS_Init(FFMS_CPU_CAPS_MMX | FFMS_CPU_CAPS_MMX2);

	/* Index the source file. Note that this example does not index any audio tracks. */
	char errmsg[1024];
	FFMS_ErrorInfo errinfo;
	errinfo.Buffer      = errmsg;
	errinfo.BufferSize  = sizeof(errmsg);
	errinfo.ErrorType   = FFMS_ERROR_SUCCESS;
	errinfo.SubType     = FFMS_ERROR_SUCCESS;
	const char *sourcefile = "somefilename";
	FFMS_Index *index = FFMS_MakeIndex(sourcefile, 0, 0, NULL, NULL, FFMS_IEH_ABORT, NULL, NULL, &amp;errinfo);
	if (index == NULL) {
		/* handle error (print errinfo.Buffer somewhere) */
	}

	/* Retrieve the track number of the first video track */
	int trackno = FFMS_GetFirstTrackOfType(index, FFMS_TYPE_VIDEO, &amp;errinfo);
	if (trackno &lt; 0) {
		/* no video tracks found in the file, this is bad and you should handle it */
		/* (print the errmsg somewhere) */
	}

	/* We now have enough information to create the video source object */
	FFMS_VideoSource *videosource = FFMS_CreateVideoSource(sourcefile, trackno, index, 1, FFMS_SEEK_NORMAL, &amp;errinfo);
	if (videosource == NULL) {
		/* handle error (you should know what to do by now) */
	}

	/* Since the index is copied into the video source object upon its creation,
	we can and should now destroy the index object. */
	FFMS_DestroyIndex(index);

	/* Retrieve video properties so we know what we're getting.
	As the lack of the errmsg parameter indicates, this function cannot fail. */
	const FFMS_VideoProperties *videoprops = FFMS_GetVideoProperties(videosource);

	/* Now you may want to do something with the info, like check how many frames the video has */
	int num_frames = videoprops->NumFrames;
	
	/* Get the first fram for examination so we know what we're getting. */
	const FFMS_Frame *propframe = FFMS_GetFrame(videosource, 0, errinfo);

	/* Now you may want to do something with the info; particularly interesting values are:
	propframe-&gt;EncodedWidth; (frame width in pixels)
	propframe-&gt;EncodedHeight; (frame height in pixels)
	propframe-&gt;EncodedPixelFormat; (actual frame colorspace)
	*/

	/* If you want to change the output colorspace or resize the output frame size,
	now is the time to do it. */
	/* See libavutil/pixfmt.h for the list of pixel formats/colorspaces.
	To get the name of a given pixel format, strip the leading PIX_FMT_
	and convert to lowercase. For example, PIX_FMT_YUV420P becomes "yuv420p". */
	int64_t pixfmt = (int64_t)1 &lt;&lt; FFMS_GetPixFmt("bgra");
	if (FFMS_SetOutputFormatV(videosource, pixfmt, propframe-&gt;EncodedWidth, propframe-&gt;EncodedHeight, FFMS_RESIZER_BICUBIC, &amp;errinfo)) {
		/* handle error */
	}

	/* now we're ready to actually retrieve the video frames */
	int framenumber = 0; /* valid until next call to FFMS_GetFrame* on the same video object */
	const FFMS_Frame *curframe = FFMS_GetFrame(videosource, framenumber, &amp;errinfo);
	if (curframe = NULL) {
		/* handle error */
	}
	/* do something with curframe */
	/* continue doing this until you're bored, or something */

	/* now it's time to clean up */
	FFMS_DestroyVideoSource(videosource);
#ifdef _WIN32
	if (com_inited)
		CoUninitialize();
#endif
	
	exit 0;
}
</pre>

<p>
And that's pretty much it. Easy, ain't it?
</p>


<h2>Indexing and You</h2>
<p>
Before opening a media file with FFMS2, you <b>must</b> index it. This is to ensure that keyframe positions, timecode data and other interesting things are known so that frame-accurate seeking is easily possible. 
</p>
<p>
There are two ways to index a media file. The first one is really a backwards compatibility thing and uses <tt>FFMS_MakeIndex</tt>. You call the function with the source filename, a binary mask representing what audio tracks you want to index (all video tracks are always automatically indexed; you have no choice in the matter), another binary mask representing what audio tracks you want to dump to Wave64 files on disk, an optional progress reporting callback and a likewise optional audio dump filename generation callback; and it will create an index object. With this method there is no way of telling ahead of time how many tracks the file has and hence the only two masks that are useful in practice are 0 (index nothing) and -1 (index everything). If you want to index only certain tracks you will have to redo the indexing after examining the index. This indexing method may be used if you only want to index video tracks, or if you want all the audio tracks regardless of how many they are, or if you already know the track layout of the file you're going to open.
</p>
<p>
The other method is a bit more sophisticated. First, you create an indexer object using <tt>FFMS_CreateIndexer</tt> and the source filename. You can then examine the indexer using <tt>FFMS_GetNumTracksI</tt>, <tt>FFMS_GetTrackTypeI</tt> and <tt>FFMS_GetCodecNameI</tt> to determine how many tracks there are and what their respective types are. When you have done so, you call <tt>FFMS_DoIndexing</tt>, which is exactly like <tt>FFMS_MakeIndex</tt> except you pass it the indexer object instead of the source filename. Since you now know the track layout, you are free to pass a more restrictive track mask to index only the tracks relevant to your interests. As with <tt>FFMS_MakeIndex</tt>, all video tracks are always indexed; the trackmask only applies to audio tracks. If you change your mind and decide there are no tracks interesting to you in the file, call <tt>FFMS_CancelIndexing</tt>. Both <tt>FFMS_DoIndexing</tt> and <tt>FFMS_CancelIndexing</tt> destroys the indexer object and frees its memory.
</p>
<p>
When you have indexed the file you can write the index object to a disk file using <tt>FFMS_WriteIndex</tt>, which is useful if you expect to open the same file more than once, since it saves you from reindexing it every time. It can be particularly time-saving with very large files or files with a lot of audio tracks, since both of those can take quite some time to index.
</p>
<p>
To create an index object from a saved disk file, use <tt>FFMS_ReadIndex</tt>. Note that the index file written has an internal version number; if you have a version of FFMS2 that isn't the same as the one that created the index, it will most likely not accept the index at all (the read function will fail). If you want to verify that a given index file actually is an index of the source file you think it is, use <tt>FFMS_IndexBelongsToFile</tt>.
</p>


<h2>Handling Unicode filenames on Windows</h2>
<p>
If you want support for Unicode filenames on Windows <tt>#define FFMS_USE_UTF8_PATHS</tt> somewhere. This will make FFMS2 assume that all strings passed to its API functions are UTF8; if they aren't either that or 7-bit ASCII, opening things will most likely fail. You can convert <tt>wchar_t</tt> strings to UTF8 using the Win32 API function <tt>WideCharToMultiByte</tt>.
</p>
<p>
Do <strong>NOT</strong> use <tt>FFMS_USE_UTF8_PATHS</tt> if you're building the FFMS2 Avisynth plugin; it'll break opening all filenames that aren't 7-bit ASCII compatible. Unfortunately you can't have both ANSI and UTF8 support in the same DLL, at least not yet. Also note that if you use this define and build FFMS2 with MinGW, some things will probably break since MinGW's iostream library doesn't support widechar filenames.
</p>
<p>
On Unix this define does nothing. You won't need to do anything special to support Unicode filenames anyway, just set your locale to something UTF8-based.
</p>


<h2>Function Reference</h2>
<p>Most functions that can fail in one way or another (as well as some that should be able to but currently don't) support error reporting using the <tt>ErrorMsg</tt> and <tt>MsgSize</tt> parameters. Example:</p>
<pre>char errmsg[1024];
FFMS_ErrorInfo errinfo;
errinfo.Buffer      = errmsg;
errinfo.BufferSize  = sizeof(errmsg);
errinfo.ErrorType   = FFMS_ERROR_SUCCESS;
errinfo.SubType     = FFMS_ERROR_SUCCESS;

const FFMS_Frame *frame = FFMS_GetFrame(vb, frameno, &amp;errinfo);
/* failure? */
if (frame == NULL) {
	printf("failed to get frame number %d, error message: %s", frameno, errinfo.Buffer);
	/* etc... */
}</pre>
<p>
How many characters you want to allocate to the error message is up to you; if you allocate too few the messages may get truncated. 1024 should be enough for anyone.
</p>

<h3>FFMS_Init - initializes the library</h3>
<pre>void FFMS_Init(int CPUFeatures)</pre>
<p>Initializes the FFMS2 library. This function must be called once at the start of your program, before doing any other FFMS2 function calls. Its only argument is an integer representing what CPU instruction sets may be used by the parts of FFmpeg that have handwritten assembler but no runtime CPU detection, i.e. libswscale and libpostproc (see <tt>FFMS_CPUFeatures</tt> in the Constants and Preprocessor Definitions section; binary OR the constants together if you want more than one). Pass 0 if you don't care; the performance hit won't be that big unless you do a lot of postprocessing or rescaling.</p>
<p>If you are on Windows, you should also initialize COM before calling this function, since the library might have been built with <tt>HAALISOURCE</tt>. If it was indeed built with <tt>HAALISOURCE</tt> but you do not intialize COM, all MPEG-TS/PS and OGM files will cause an error when you try to open them. All other file types will work normally. Typically, you'd initialize COM something like the following:</p>
<pre>#include &lt;objbase.h&gt;
/* later on, in the actual code... */
bool com_inited = false;
HRESULT res = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (SUCCEEDED(res)) 
	com_inited = true;
else if (res != RPC_E_CHANGED_MODE) {
	/* com initialization failed, handle error */
}
/* your code goes here */
/* and after you're done: */
if (com_inited)
	CoUninitialize();
</pre>

<h3>FFMS_GetLogLevel - gets ffmpeg message level</h3>
<pre>int FFMS_GetLogLevel()</pre>
<p>Retrieves ffmpeg's current logging/message level (i.e. how much diagnostic noise it prints to <tt>STDERR</tt>). If you want to make any sense of the returned value you'd better <tt>#include &lt;libavutil/log.h&gt;</tt> from the ffmpeg source tree to get the relevant constant definitions. Alternatively, just copy the relevant constant definitions into your own code and hope the ffmpeg devs doesn't change them randomly for no particular reason like they do with everything else.
</p>

<h3>FFMS_SetLogLevel - sets ffmpeg message level</h3>
<pre>void FFMS_SetLogLevel(int Level)</pre>
<p>Sets ffmpeg's logging/message level; see <tt>FFMS_GetLogLevel()</tt> for details.</p>

<h3>FFMS_CreateVideoSource - creates a video source object</h3>
<pre>FFMS_VideoSource *FFMS_CreateVideoSource(const char *SourceFile, int Track, FFMS_Index *Index,
	int Threads, int SeekMode, FFMS_ErrorInfo *ErrorInfo)</pre>
<p>Creates a <tt>FFMS_VideoSource</tt> object with the given properties. The <tt>FFMS_VideoSource</tt> object represents a video stream, and can be passed to other functions to retreive frames and metadata from said stream. The video stream in question must be indexed first (see the indexing functions). Note that the index object is copied into the <tt>FFMS_VideoSource</tt> object upon its creation, so once you've created the video source you can generally destroy the index object immediately, since all info you can retrieve from it is also retrievable from the <tt>FFMS_VideoSource</tt> object.
</p>
<h4>Arguments</h4>
<p><b><tt>const char *SourceFile</tt></b><br />
The source file to open. Can be an absolute or relative path.</p>
<p><b><tt>int Track</tt></b><br />
The track number of the video track to open, as seen by the relevant demuxer. See <tt>FFMS_GetNumTracks</tt>, <tt>FFMS_GetTrackType</tt>, <tt>FFMS_GetFirstTrackOfType</tt> and their variants for further information on how to determine this.</p>
<p><b><tt>FFMS_Index *Index</tt></b><br />
A pointer to a FFMS_Index object containing indexing information for the track you want to open.</p>
<p><b><tt>int Threads</tt></b><br />
The number of decoding threads to use. Passing funny values like 0 or -1 may lead to undefined behavior so you better sanity check the input if you let the user set this. Values &gt;1 have no effect if ffmpeg was not compiled with threading support.</p>
<p><b><tt>int SeekMode</tt></b><br />
Controls how seeking (random access) is handled and hence affects frame accuracy. You will almost always want to use <tt>FFMS_SEEK_NORMAL</tt>. Has no effect on Matroska files, where the equivalent of <tt>FFMS_SEEK_NORMAL</tt> is always used. For a list of valid values, see the Constants and Preprocessor Definitions section.</p>
<p><b><tt>FFMS_ErrorInfo *ErrorInfo</tt></b><br />
See above.</p>
<h4>Return values</h4>
<p>Returns a pointer to the created <tt>FFMS_VideoSource</tt> object on success. Returns <tt>NULL</tt> and sets <tt>ErrorMsg</tt> on failure.</p>

<h3>FFMS_CreateAudioSource - creates an audio source object</h3>
<pre>FFMS_AudioSource *FFMS_CreateAudioSource(const char *SourceFile, int Track, FFMS_Index *Index,
	FFMS_ErrorInfo *ErrorInfo)</pre>
<p>
Does exactly the same thing as <tt>FFMS_CreateVideoSource</tt>, but for audio tracks. Arguments and return values are identical. Do note that audio support is somewhat experimental and not guaranteed to be sample-accurate.
</p>

<h3>FFMS_DestroyVideoSource, FFMS_DestroyAudioSource - deallocates a video or audio source object</h3>
<pre>void FFMS_DestroyVideoSource(FFMS_VideoSource *V)
void FFMS_DestroyAudioSource(FFMS_AudioSource *A)</pre>
<p>
Deallocates the given <tt>FFMS_VideoSource</tt> or <tt>FFMS_AudioSource</tt> object and frees the memory allocated by <tt>FFMS_CreateVideoSource</tt> or <tt>FFMS_CreateAudioSource</tt>, respectively.
</p>

<h3>FFMS_GetVideoProperties - retrieves video properties</h3>
<pre>const FFMS_VideoProperties *FFMS_GetVideoProperties(FFMS_VideoSource *V)</pre>
<p>
Retreives the video properties from the given <tt>FFMS_VideoSource</tt> object and stores them in a <tt>FFMS_VideoProperties</tt> struct (see the Data Structures section below). Returns a pointer to said struct.
</p>

<h3>FFMS_GetAudioProperties - retrieves audio properties</h3>
<pre>const FFMS_AudioProperties *FFMS_GetAudioProperties(FFMS_AudioSource *A)</pre>
<p>Does the exact same thing as <tt>FFMS_GetVideoProperties</tt>, but for an <tt>FFMS_AudioSource</tt> object.
</p>

<h3>FFMS_GetFrame - retrieves a given video frame</h3>
<pre>const FFMS_Frame *FFMS_GetFrame(FFMS_VideoSource *V, int n, FFMS_ErrorInfo *ErrorInfo)</pre>
<p>Gets and decodes a video frame from the video stream represented by the given <tt>FFMS_VideoSource</tt> object and stores it in a <tt>FFMS_Frame</tt> struct. The colorspace and resolution of the frame can be changed by calling <tt>FFMS_SetOutputFormatV</tt> with the appropriate parameters before calling this function. Note that this function is not threadsafe (you can only request one frame at a time from a given <tt>FFMS_VideoSource</tt> object) and that the returned pointer to the FFMS_Frame is a <i>const</i> pointer.
</p>
<h4>Arguments</h4>
<p><b><tt>FFMS_VideoSource *V</tt></b><br />
A pointer to the <tt>FFMS_VideoSource</tt> object that represents the video stream you want to retrieve a frame from.</p>
<p><b><tt>int n</tt></b><br />
The frame number to get. Frame numbering starts from zero, and hence the first frame is number 0 (not 1) and the last frame is number <tt>FFMS_VideoProperties->NumFrames</tt> minus 1. Requesting a frame number beyond the stream end or before the stream start (i.e. negative) may cause undefined behavior.</p>
<p><b><tt>FFMS_ErrorInfo *ErrorInfo</tt></b><br />
See above.</p>
<h4>Return values</h4>
<p>Returns a pointer to the <tt>FFMS_Frame</tt> on success. Returns <tt>NULL</tt> and sets <tt>ErrorMsg</tt> on failure.</p>

<h3>FFMS_GetFrameByTime - retrieves a video frame at a given timestamp</h3>
<pre>const FFMS_Frame *FFMS_GetFrameByTime(FFMS_VideoSource *V, double Time, FFMS_ErrorInfo *ErrorInfo)</pre>
<p>Does the exact same thing as <tt>FFMS_GetFrame</tt> except instead of giving it a frame number you give it a timestamp in milliseconds, and it will retrieve the frame that starts closest to that timestamp. This function exists for the people who are too lazy to build and traverse a mapping between frame numbers and timestamps themselves. Note that it is measurably slower than <tt>FFMS_GetFrame</tt>.
</p>

<h3>FFMS_GetAudio - decodes a number of audio samples</h3>
<pre>int FFMS_GetAudio(FFMS_AudioSource *A, void *Buf, int64_t Start, int64_t Count, FFMS_ErrorInfo *ErrorInfo)</pre>
<p>Decodes the requested audio samples from the audio stream represented by the given <tt>FFMS_AudioSource</tt> object and stores them in the given buffer. Note that this function is not threadsafe; you can only request one decoding operation at a time from a given <tt>FFMS_AudioSource</tt> object.
</p>
<h4>Arguments</h4>
<p><b><tt>FFMS_AudioSource *A</tt></b><br />
A pointer to the <tt>FFMS_AudioSource</tt> object that represents the audio stream you want to get samples from.</p>
<p><b><tt>void *Buf</tt></b><br />
A pointer to the buffer where the decoded samples will end up. You are responsible for allocating and freeing this buffer yourself, so you better check the <tt>FFMS_AudioProperties</tt> for the sample format, number of channels, channel layout etc first, so you know how much memory you need to allocate. The formula to calculate the required size of the buffer is (obviously) <tt>num_bytes = bytes_per_sample * num_channels * num_samples</tt>.</p>
<p><b><tt>int64_t Start, int64_t Count</tt></b><br />
The range of samples you want decoded. The output is <tt>Count</tt> samples long, starting from <tt>Start</tt> (inclusive). Like video frame numbers, sample numbers start from zero and hence the last sample in the stream is number <tt>FFMS_AudioProperties->NumSamples</tt> minus 1. Requesting samples beyond the stream end or before the stream start may result in undefined behavior.
</p>
<p><b><tt>FFMS_ErrorInfo *ErrorInfo</tt></b><br />
See above.</p>
<h4>Return values</h4>
<p>Returns 0 on success. Returns non-0 and sets <tt>ErrorMsg</tt> on failure.</p>

<h3>FFMS_SetOutputFormatV - sets the output format for video frames</h3>
<pre>int FFMS_SetOutputFormatV(FFMS_VideoSource *V, int64_t TargetFormats, int Width, int Height, int Resizer,
	FFMS_ErrorInfo *ErrorInfo)</pre>
<p>Sets the colorspace and frame dimensions to be used for output of frames from the given <tt>FFMS_VideoSource</tt> by all further calls to <tt>FFMS_GetFrame</tt> and <tt>FFMS_GetFrameByTime</tt>, until next time you call <tt>FFMS_SetOutputFormatV</tt> or <tt>FFMS_ResetOutputFormatV</tt>. You can change the output format at any time without having to reinitialize the <tt>FFMS_VideoSource</tt> object or anything else. Can be used to convert the video to grayscale or monochrome if you are so inclined. If you provided a list of more than one colorspace/pixelformat, you should probably check the <tt>FFMS_Frame</tt> properties afterwards to see which one got selected.
</p>
<h4>Arguments</h4>
<p><b><tt>FFMS_VideoSource *V</tt></b><br />
A pointer to the <tt>FFMS_VideoSource</tt> object that represents the video stream you want to change the output format for.</p>
<p><b><tt>int64_t TargetFormats</tt></b><br />
The desired output colorspace(s). You may binary OR several colorspaces you are willing to accept together; the function will then choose the colorspace that gives the least lossy conversion from the source colorspace. To get the integer constant representing a given colorspace, see <tt>FFMS_GetPixFmt</tt>. Once you have the integer constant(s), shift 1 left by each constant to get the value suitable for passing as this argument. Example:<br /><tt>int64_t targetformats = (1 &lt;&lt; pixfmt1) | (1 &lt;&lt; pixfmt2) | (1 &lt;&lt; pixfmt3);</tt></p>
<p><b><tt>int Width, int Height</tt></b><br />
The desired image dimensions, in pixels. If you do not want to resize just pass the input dimensions. Passing invalid dimensions (like 0 or negative) has undefined behavior.</p>
<p><b><tt>int Resizer</tt></b><br />
The desired image resizing algorithm, represented by an integer as enumerated in <tt>FFMS_Resizers</tt> (see the Constants and Preprocessor Definitions section). You must choose one even if you're not actually rescaling the image, because the video may change resolution mid-stream and then you will be using a resizer whether you want it or not (you will only know that the resolution changed after you actually decoded a frame with a new resolution), and it may also get used for rescaling subsampled chroma planes.</p>
<p><b><tt>FFMS_ErrorInfo *ErrorInfo</tt></b><br />
See above.</p>
<h4>Return values</h4>
<p>Returns 0 on success. Returns non-0 and sets <tt>ErrorMsg</tt> on failure.</p>

<h3>FFMS_ResetOutputFormatV - resets the video output format</h3>
<pre>void FFMS_ResetOutputFormatV(FFMS_VideoSource *V)</pre>
<p>
Resets the output format for the given <tt>FFMS_VideoSource</tt> object so that no conversion takes place. Note that the results of this function may vary wildly, particularly if the video changes resolution mid-stream. If you call it, you'd better call <tt>FFMS_GetFrame</tt> afterwards and examine the properties to see what you actually ended up with.
</p>

<h3>FFMS_SetPP - sets postprocessing options</h3>
<pre>int FFMS_SetPP(FFMS_VideoSource *V, const char *PP, FFMS_ErrorInfo *ErrorInfo)</pre>
<p>
Sets the postprocessing filter chain that will be applied to frames retrieved from the given <tt>FFMS_VideoSource</tt> object by all further calls to <tt>FFMS_GetFrame</tt> and <tt>FFMS_GetFrameByTime</tt> until the next call to <tt>FFMS_SetPP</tt> or <tt>FFMS_ResetPP</tt>. The filter chain is described by a text string; see the PP string format section below for details.
<h4>Arguments</h4>
<p><b><tt>FFMS_VideoSource *V</tt></b><br />
A pointer to the <tt>FFMS_VideoSource</tt> object that represents the video stream you want to change the postprocessing settings for.</p>
<p><b><tt>const char *PP</tt></b><br />
A string describing the desired postprocessing. See the PP string format section below for details. Pass <tt>NULL</tt> or an empty string to disable postprocessing.</p>
<p><b><tt>FFMS_ErrorInfo *ErrorInfo</tt></b><br />
See above.</p>
<h4>Return values</h4>
<p>Returns 0 on success. Returns non-0 and sets <tt>ErrorMsg</tt> on failure.</p>
</p>

<h3>FFMS_ResetPP - resets postprocessing options</h3>
<pre>void FFMS_ResetPP(FFMS_VideoSource *V)</pre>
<p>
Resets the postprocessing filter chain that will be applied to frames retrieved from the given <tt>FFMS_VideoSource</tt> object by all further calls to <tt>FFMS_GetFrame</tt> and <tt>FFMS_GetFrameByTime</tt> until the next call to <tt>FFMS_SetPP</tt> or <tt>FFMS_ResetPP</tt> so that no postprocessing will be applied. Is equivalent to <tt>FFMS_SetPP(VideoSource, NULL, ErrorInfo)</tt> but is more efficient.
</p>

<h3>FFMS_DestroyIndex - deallocates an index object</h3>
<pre>void FFMS_DestroyFFMS_Index(FFMS_Index *Index)</pre>
<p>Deallocates the given <tt>FFMS_Index</tt> object and frees the memory that was allocated when it was created.
</p>

<h3>FFMS_GetSourceType - gets which source module was used to open the given index</h3>
<pre>int FFMS_GetSourceType(FFMS_Index *Index)</pre>
<p>
Checks which source module (libavformat, Haali's Matroska parsing library, or Haali's DirectShow splitter) was used when opening the file represented by the given <tt>FFMS_Index</tt> and returns an integer (as enumerated in <tt>FFMS_Sources</tt>; see the Constants and Preprocessor Definitions section below) that represents it.
</p>

<h3>FFMS_GetFirstTrackOfType - gets the track number of the first track of a given type</h3>
<pre>int FFMS_GetFirstTrackOfType(FFMS_Index *Index, int TrackType, FFMS_ErrorInfo *ErrorInfo)</pre>
<p>Finds the first track of the given <tt>FFMS_TrackType</tt> in the given <tt>FFMS_Index</tt> and returns its track number, suitable for use as an argument to <tt>FFMS_CreateVideoSource</tt> or <tt>FFMS_CreateAudioSource</tt>, as well as to some other functions.
</p>
<h4>Arguments</h4>
<p><b><tt>FFMS_Index *Index</tt></b><br />
A pointer to the <tt>FFMS_Index</tt> object that represents the media file you want to look for tracks in.</p>
<p><b><tt>int TrackType</tt></b><br />
The track type to look for. See <tt>FFMS_TrackType</tt> in the Constants and Preprocessor Definitions" section for valid values.</p>
<p><b><tt>FFMS_ErrorInfo *ErrorInfo</tt></b><br />
See above.</p>
<h4>Return values</h4>
<p>Returns the track number (an integer greater than or equal to 0) on success. Returns a negative integer and sets ErrorMsg on failure (i.e. if no track of the given type was found).</p>

<h3>FFMS_GetFirstIndexedTrackOfType - gets the track number of the first track of a given type</h3>
<pre>int FFMS_GetFirstIndexedTrackOfType(FFMS_Index *Index, int TrackType, FFMS_ErrorInfo *ErrorInfo)</pre>
<p>Does the exact same thing as <tt>FFMS_GetFirstTrackOfType</tt> but ignores tracks that have not been indexed.
</p>

<h3>FFMS_GetNumTracks - gets the number of tracks in a given index</h3>
<pre>int FFMS_GetNumTracks(FFMS_Index *Index)</pre>
<p>Returns the total number of tracks in the media file represented by the given <tt>FFMS_Index</tt>.
</p>

<h3>FFMS_GetNumTracksI - gets the number of tracks in a given indexer</h3>
<pre>int FFMS_GetNumTracksI(FFMS_Indexer *Indexer)</pre>
<p>Returns the total number of tracks in the media file represented by the given <tt>FFMS_Indexer</tt>. In other words, does the same thing as <tt>FFMS_GetNumTracks</tt> but does not require indexing the entire file first.
</p>

<h3>FFMS_GetTrackType - gets the track type of a given track</h3>
<pre>int FFMS_GetTrackType(FFMS_Track *T)</pre>
<p>Returns an integer representing the <tt>FFMS_TrackType</tt> (see the Constants and Preprocessor Definitions section) of the track represented by the given <tt>FFMS_Track</tt> object.
</p>

<h3>FFMS_GetTrackTypeI - gets the track type of a given track</h3>
<pre>int FFMS_GetTrackTypeI(FFMS_Indexer *Indexer, int Track)</pre>
<p>Returns an integer representing the <tt>FFMS_TrackType</tt> (see the Constants and Preprocessor Definitions section) of the track number <tt>Track</tt> in the media file represented by the given <tt>FFMS_Indexer</tt>. In other words, does the same thing as <tt>FFMS_GetTrackType</tt>, but does not require having indexed the file first. If you have indexed the file, use <tt>FFMS_GetTrackType</tt> instead since the <tt>FFMS_Indexer</tt> object is destructed when the index is created. Note that specifying an invalid track number may lead to undefined behavior.
</p>

<h3>FFMS_GetCodecNameI - gets the name of the codec used for a given track</h3>
<pre>const char *FFMS_GetCodecNameI(FFMS_Indexer *Indexer, int Track)</pre>
<p>Returns the human-readable name ("long name" in ffmpeg terms) of the codec used in the given track number in the media file represented by the given <tt>FFMS_Indexer</tt> object. Useful if you want to, say, pop up a menu asking the user which tracks he or she wishes to index. Note that specifying an invalid track number may lead to undefined behavior.
</p>

<h3>FFMS_GetNumFrames - gets the number of frames in a given track</h3>
<pre>int FFMS_GetNumFrames(FFMS_Track *T)</pre>
<p>Returns the number of frames in the track represented by the given <tt>FFMS_Track</tt>. For a video track this is the number of video frames, which can be useful; for an audio track it's the number of packets, which is almost never useful, since nothing in the API exposes those. A return value of 0 indicates the track has not been indexed.
</p>

<h3>FFMS_GetFrameInfo - gets information about a given frame</h3>
<pre>const FFMS_FrameInfo *FFMS_GetFrameInfo(FFMS_Track *T, int Frame)</pre>
<p>Gets information about the given frame (identified by its frame number) from the indexing information in the given <tt>FFMS_Track</tt> and stores it in a <tt>FFMS_FrameInfo</tt> struct. See the Data Structures section below for more information. Using this function on a <tt>FFMS_Track</tt> representing a non-video track has undefined behavior.
</p>
<h4>Arguments</h4>
<p><b><tt>FFMS_Track *T</tt></b><br />
A pointer to the <tt>FFMS_Track</tt> object that represents the video track containing the frame you want to get information about.</p>
<p><b><tt>int Frame</tt></b><br />
The frame number to get information about. See <tt>FFMS_GetFrame</tt> for information about frame numbers. Requesting information about a frame before the start or after the end of the video track may result in undefined behavior, so don't do that.</p>
<p><b><tt>FFMS_ErrorInfo *ErrorInfo</tt></b><br />
See above.</p>
<h4>Return values</h4>
<p>Returns a pointer to the <tt>FFMS_FrameInfo</tt> struct on success. Returns <tt>NULL</tt> and sets <tt>ErrorMsg</tt> on failure.</p>

<h3>FFMS_GetTrackFromIndex - retrieves track info from an index</h3>
<pre>FFMS_Track *FFMS_GetTrackFromIndex(FFMS_Index *Index, int Track)</pre>
<p>Gets track data for the given track number from the given <tt>FFMS_Index</tt> object, stores it in a <tt>FFMS_Track</tt> object and returns a pointer to it. Use this function if you don't want to (or cannot) open the track with <tt>FFMS_CreateVideoSource</tt> or <tt>FFMS_CreateAudioSource</tt> first. If you already have a <tt>FFMS_VideoSource</tt> or <tt>FFMS_AudioSource</tt> object it's safer to use <tt>FFMS_GetTrackFromVideo</tt> or <tt>FFMS_GetTrackFromAudio</tt> (see below) instead. Note that specifying a nonexistent or invalid track number leads to undefined behavior (usually an access violation). Also note that the returned <tt>FFMS_Track</tt> object is only valid until its parent <tt>FFMS_Index</tt> object is destroyed.
</p>
<h4>Arguments</h4>
<p><b><tt>FFMS_Index *Index</tt></b><br />
A pointer to the <tt>FFMS_Index</tt> object that represents the media file containing the track whose index information you want to get.</p>
<p><b><tt>int Track</tt></b><br />
The track number, as seen by the relevant demuxer (see <tt>FFMS_GetNumTracks</tt>, <tt>FFMS_GetTrackType</tt>, <tt>FFMS_GetFirstTrackOfType</tt> and their variants).</p>
<p><b><tt>FFMS_ErrorInfo *ErrorInfo</tt></b><br />
See above.</p>
<h4>Return values</h4>
<p>Returns the <tt>FFMS_Track</tt> on success. Note that requesting indexing information for a track that has not been indexed will not cause an error, it will just return an empty <tt>FFMS_Track</tt> (check for >0 frames using <tt>FFMS_GetNumFrames</tt> to see if the returned object actually contains indexing information).</p>

<h3>FFMS_GetTrackFromVideo, FFMS_GetTrackFromAudio - retrieves track info from audio or video source</h3>
<pre>FFMS_Track *FFMS_GetTrackFromVideo(FFMS_VideoSource *V)
FFMS_Track *FFMS_GetTrackFromAudio(FFMS_AudioSource *A)</pre>
<p>Gets information about the track represented by the given <tt>FFMS_VideoSource</tt> or <tt>FFMS_AudioSource</tt> object and returns a pointer to a <tt>FFMS_Track</tt> object containing said information. It's generally safer to use these functions instead of <tt>FFMS_GetTrackFromIndex</tt>, since unlike that function they cannot cause access violations if you specified an nonexistent tracknumber, return a <tt>FFMS_Track</tt> that doesn't actually contain any indexing information, or return an object that ceases to be valid when the index is destroyed. Note that the returned <tt>FFMS_Track</tt> object is only valid until its parent <tt>FFMS_VideoSource</tt> or <tt>FFMS_AudioSource</tt> object is destroyed.
</p>

<h3>FFMS_GetTimeBase - retrieves the time base for the given track</h3>
<pre>const FFMS_TrackTimeBase *FFMS_GetTimeBase(FFMS_Track *T)</pre>
<p>Finds the basic time unit for the track represented by the given <tt>FFMS_Track</tt>, stores it in a <tt>FFMS_TrackTimeBase</tt> struct and returns a pointer to said struct. See the Data Structures section for information about the time base; note that it is only meaningful for video tracks.
</p>

<h3>FFMS_WriteTimecodes - writes timecodes for the given track to disk</h3>
<pre>int FFMS_WriteTimecodes(FFMS_Track *T, const char *TimecodeFile, FFMS_ErrorInfo *ErrorInfo)</pre>
<p>Writes Matroska v2 timecodes for the track represented by the given <tt>FFMS_Track</tt> to the given file. Only meaningful for video tracks.
</p>
<h4>Arguments</h4>
<p><b><tt>FFMS_Track *T</tt></b><br />
A pointer to the <tt>FFMS_Track</tt> object that represents the video track you want to write timecodes for.</p>
<p><b><tt>const char *TimecodeFile</tt></b><br />
The filename to write to. Can be a relative or absolute path. The file will be truncated and overwritten if it already exists.</p>
<p><b><tt>FFMS_ErrorInfo *ErrorInfo</tt></b><br />
See above.</p>
<h4>Return values</h4>
<p>Returns 0 on success. Returns non-0 and sets <tt>ErrorMsg</tt> on failure.</p>

<h3>FFMS_MakeIndex - indexes a given source file</h3>
<pre>FFMS_Index *FFMS_MakeIndex(const char *SourceFile, int IndexMask, int DumpMask,
	TAudioNameCallback ANC, void *ANCPrivate, bool IgnoreDecodeErrors, TIndexCallback IC, void *ICPrivate,
	FFMS_ErrorInfo *ErrorInfo)</pre>
<p>Indexes all video tracks and the given audio tracks in the given media file and returns a <tt>FFMS_Index</tt> object representing the file in question. Can also decode and write audio tracks to Wave64 files on disk while indexing.
</p>
<h4>Arguments</h4>
<p><b><tt>const char *SourceFile</tt></b><br />
The filename of the media file to index. Can be a relative or absolute path.</p>
<p><b><tt>int IndexMask, int DumpMask</tt></b><br />
Binary masks of the track numbers of the audio tracks to index and decode to disk, respectively. Pass 0 to index/decode no audio tracks, or -1 to index/decode all. Decoding a track means it will automatically be indexed regardless of what the <tt>IndexMask</tt> says, but indexing a track does not automatically mean that it will be decoded.</p>
<p><b><tt>TAudioNameCallback ANC</tt></b><br />
A function pointer to a callback function that will generate the filename(s) for the dumped audio tracks. To get the default filename(s), pass <tt>&amp;FFMS_DefaultAudioFilename</tt>. See <i>Callbacks</i> below for details if you want to write your own function. If the <tt>DumpMask</tt> is 0, you may pass <tt>NULL</tt> here.
</p>
<p><b><tt>void *ANCPrivate</tt></b><br />
A pointer of your choice that will be passed as an argument to the audio filename generation callback function. See <i>Callbacks</i> below for details. If <tt>DumpMask</tt> is 0, you may pass <tt>NULL</tt> here. If you are using <tt>FFMS_DefaultAudioFilename</tt>, you must pass a format string here. See the Audio Filename Format Strings section for details.
</p>
<p><b><tt>bool IgnoreDecodeErrors</tt></b><br />
If true, audio decoding errors will not cause indexing to fail. Tracks that cannot be decoded will not be indexed, however. Has no effect if the <tt>DumpMask</tt> is non-zero, in which case audio decoding errors will always cause the indexing to fail.</p>
<p><b><tt>TIndexCallback IC</tt></b><br />
A function pointer to a callback function that can be used to update progress. See <i>Callbacks</i> below for details.</p>
<p><b><tt>void *ICPrivate</tt></b><br />
A pointer of your choice that will be passed as an argument to the progress reporting callback function. See <i>Callbacks</i> below for details.</p>
<p><b><tt>FFMS_ErrorInfo *ErrorInfo</tt></b><br />
See above.</p>
<h4>Callbacks</h4>
<p>This function has two potential callbacks. One can, if you so desire, call your code back intermittently so you can see how the indexing is progressing. This is accomplished using a function pointer to a function with the following signature:
</p>
<pre>int FFMS_CC FunctionName(int64_t Current, int64_t Total, void *ICPrivate)</pre>
<p> The callback function's arguments are as follows:</p>
<ul>
<li><tt><b>int64_t Current, int64_t Total</b></tt> - The indexing progress (amount done/total amount).</li>
<li><tt><b>void *Private</b></tt> - the same pointer as the one you passed as the <tt>Private</tt> argument to <tt>FFMS_MakeIndex</tt>. Can be used for anything you like, but one example (in a GUI program) is to use it for passing a progress ticker object that you can update with each call to the indexing function.</li>
</ul>
<p>Return 0 from the callback function to continue indexing, non-0 to cancel indexing (returning non-0 will make <tt>FFMS_MakeIndex</tt> fail with the reason "indexing cancelled by user").
</p>
<p>
The other callback is used to generate the filename(s) of the audio file(s) written if <tt>DumpMask</tt> is non-zero. It has the following signature:
</p>
<pre>int FFMS_CC FunctionName(const char *SourceFile, int Track, const FFMS_AudioProperties *AP,
	char *FileName, int FNSize, void *Private)</pre>
<p>The callback function is called twice for each audio file generated. The first time <tt>FileName</tt> is <tt>NULL</tt>, and you should return the number of characters your generated filename will use plus one, and do nothing else. The second time <tt>FileName</tt> is a pointer to a pre-allocated array of char; you should write your generated filename to that and return the number of characters actually written plus one. Generally the easiest way to do this in both cases is to use <tt>snprintf</tt>. See the implementation of <tt>GenAudioFilename</tt> in ffmsindex.cpp for an example on how to do it.<br />
The callback function's arguments are as follows:</p>
<ul>
<li><tt><b>const char *SourceFile</b></tt> - The name of the source media file.</li>
<li><tt><b>int Track</b></tt> - The track number of the audio track being dumped.</li>
<li><tt><b>const FFMS_AudioProperties *AP</b></tt> - A pointer to the <tt>FFMS_AudioProperties</tt> struct containing information about the audio track being dumped. Note that the <tt>LastTime</tt> field is not defined since the last timestamp has not yet been encountered during indexing.</li>
<li><tt><b>char *FileName</b></tt> - A pointer to the string to which the callback function should write the generated filename (see above).</li>
<li><tt><b>int FNSize</b></tt> - The length of the <tt>FileName</tt> string.</li>
<li><tt><b>void *Private</b></tt> - The <tt>ANCPrivate</tt> pointer passed to <tt>FFMS_MakeIndex</tt>. Can be used to store data between calls, or to give audio tracks individual names that aren't just based on their properties.</li>
</ul>
<p>Most of the parameters may seem pointless since you don't need to use them, but they are passed so that you can easily generate a filename based on the audio track's properties if you want to.
</p>
<h4>Return values</h4>
<p>Returns a pointer to the created <tt>FFMS_Index</tt> on success. Returns <tt>NULL</tt> and sets <tt>ErrorMsg</tt> on failure.</p>

<h3>FFMS_DefaultAudioFilename - default callback for audio filename generation</h3>
<p>This function generates a default audio filename for use when dumping audio tracks to disk as Wave64 files during indexing. Its only use in the public API is as a default callback for <tt>FFMS_MakeIndex</tt> and <tt>FFMS_DoIndexing</tt>; you should never call it directly. See <tt>FFMS_MakeIndex</tt> for a description of its arguments.</p>

<h3>FFMS_CreateIndexer - creates an indexer object for the given file</h3>
<pre>FFMS_Indexer *FFMS_CreateIndexer(const char *SourceFile, FFMS_ErrorInfo *ErrorInfo)</pre>
<p>Creates a <tt>FFMS_Indexer</tt> object for the given <tt>SourceFile</tt> and returns a pointer to it. See Indexing and You for details on how to use the indexer.</p>
<h4>Return values</h4>
<p>Returns a pointer to the <tt>FFMS_Indexer</tt> on success. Returns <tt>NULL</tt> and sets <tt>ErrorMsg</tt> on failure.</p>

<h3>FFMS_DoIndexing - indexes the file represented by an indexer object</h3>
<pre>FFMS_Index *FFMS_DoIndexing(FFMS_Indexer *Indexer, int IndexMask, int DumpMask,
	TAudioNameCallback ANC, void *ANCPrivate, bool IgnoreDecodeErrors, TIndexCallback IC, void *ICPrivate,
	FFMS_ErrorInfo *ErrorInfo)</pre>
<p>Does the exact same thing as <tt>FFMS_MakeIndex</tt>, but takes an indexer object instead of a source filename. Return values and arguments are identical to <tt>FFMS_MakeIndex</tt>; see that function for details. See the Indexing and You section for more details about indexing. Note that calling this function destroys the <tt>FFMS_Indexer</tt> object and frees the memory allocated by <tt>FFMS_CreateIndexer</tt>.</p>

<h3>FFMS_CancelIndexing - destroys the given indexer object</h3>
<pre>void FFMS_CancelIndexing(FFMS_Indexer *Indexer)</pre>
<p>Destroys the given <tt>FFMS_Indexer</tt> object and frees the memory allocated by <tt>FFMS_CreateIndexer</tt>.</p>

<h3>FFMS_ReadIndex - reads an index file from disk</h3>
<pre>FFMS_Index *FFMS_ReadIndex(const char *IndexFile, FFMS_ErrorInfo *ErrorInfo)</pre>
<p>Attempts to read indexing information from the given <tt>IndexFile</tt>, which can be an absolute or relative path. Returns the <tt>FFMS_Index</tt> on success; returns <tt>NULL</tt> and sets <tt>ErrorMsg</tt> on failure.
</p>

<h3>FFMS_IndexBelongsToFile - check if a given index belongs to a given file</h3>
<pre>int FFMS_IndexBelongsToFile(FFMS_Index *Index, const char *SourceFile, FFMS_ErrorInfo *ErrorInfo)</pre>
<p>Makes a heuristic (but very reliable) guess about whether the given <tt>FFMS_Index</tt> is an index of the given <tt>SourceFile</tt> or not. Useful to determine if the index object you just read with <tt>FFMS_ReadIndex</tt> is actually relevant to your interests, since the only two ways to pair up index files with source files are a) trust the user blindly, or b) comparing the filenames; neither is very reliable.
</p>
<h4>Arguments</h4>
<p><b><tt>FFMS_Index *Index</tt></b><br />
The index object to check.</p>
<p><b><tt>const char *SourceFile</tt></b><br />
The source file to verify the index against.</p>
<h4>Return values</h4>
<p>Returns 0 if the given index is determined to belong to the given file. Returns non-0 and sets <tt>ErrorMsg</tt> otherwise.</p>

<h3>FFMS_WriteIndex - writes an index object to disk</h3>
<pre>int FFMS_WriteIndex(const char *IndexFile, FFMS_Index *TrackIndices, FFMS_ErrorInfo *ErrorInfo)</pre>
<p>Writes the indexing information from the given <tt>FFMS_Index</tt> to the given <tt>IndexFile</tt> (which can be an absolute or relative path; it will be truncated and overwritten if it already exists). Returns 0 on success; returns non-0 and sets <tt>ErrorMsg</tt> on failure.
</p>

<h3>FFMS_GetPixFmt - gets a colorspace identifier from a colorspace name</h3>
<pre>int FFMS_GetPixFmt(const char *Name)</pre>
<p>Translates a given colorspace/pixel format <tt>Name</tt> to an integer constant representing it, suitable for passing to <tt>FFMS_SetOutputFormatV</tt> (after some manipulation, see that function for details). This function exists so that you don't have to include a ffmpeg header file in every single program you ever write. For a list of colorspaces and their names, see <tt>libavutil/pixfmt.h</tt>. To get the name of a colorspace, strip the leading <tt>PIX_FMT_</tt> and convert the remainder to lowercase. For example, the name of <tt>PIX_FMT_YUV420P</tt> is <tt>yuv420p</tt>. It is strongly recommended to use this function instead of including pixfmt.h directly, since this function guarantees that you will always get the constant definitions from the version of ffmpeg that FFMS2 was linked against.
</p>
<h4>Arguments</h4>
<p><b><tt>const char *Name</tt></b><br />
The name of the desired colorspace/pixel format, as a nul-terminated ASCII string.</p>
<h4>Return values</h4>
<p>Returns the integer constant representing the given colorspace/pixel format on success. Returns the integer constant representing <tt>PIX_FMT_NONE</tt> (that is, -1) on failure (i.e. if no matching colorspace was found), but note that you can call <tt>FFMS_GetPixFmt("none")</tt> and get the same return value without it being a failed call, strictly speaking.</p>

<h3>FFMS_GetPresentSources - checks what source modules the library was compiled with</h3>
<pre>int FFMS_GetPresentSources()</pre>
<p>
Checks which source modules the library was compiled with and returns an integer by binary OR'ing the relevant constants from <tt>FFMS_Sources</tt> together.
</p>

<h3>FFMS_GetEnabledSources - checks what source modules are actually available for use</h3>
<pre>int FFMS_GetEnabledSources()</pre>
<p>
Does the same thing as <tt>FFMS_GetPresentSources</tt> but checks what source modules are actually available for use instead of which ones are compiled in.
</p>


<h2>Data Structures</h2>
<p>
The following public data structures may be of interest.
</p>

<h3>FFMS_Frame</h3>
<pre>typedef struct {
	uint8_t *Data[4];
	int Linesize[4];
	int EncodedWidth;
	int EncodedHeight;
	int EncodedPixelFormat;
	int ScaledWidth;
	int ScaledHeight;
	int ConvertedPixelFormat;
	int KeyFrame;
	int RepeatPict;
	int InterlacedFrame;
	int TopFieldFirst;
	char PictType;
} FFMS_Frame;</pre>
<p>A struct representing a video frame. The fields are:</p>
<ul>
<li><b><tt>uint8_t *Data[4]</tt></b> - An array of pointers to the picture planes (fields containing actual pixel data). Planar formats use more than one plane, for example YV12 uses one plane each for the Y, U and V data. Packed formats (such as the various RGB32 flavors) use only the first plane. If you want to determine if plane <tt>i</tt> contains data or not, check for <tt>FFMS_Frame-&gt;Linesize[i] &gt; 0</tt>.</li>
<li><b><tt>int Linesize[4]</tt></b> - An array of integers representing the length of each scan line in each of the four picture planes, in bytes. In alternative terminology, this is the "pitch" of the plane. Usually, the total size in bytes of picture plane <tt>i</tt> is <tt>FFMS_Frame-&gt;Linesize[i] * FFMS_VideoProperties-&gt;Height</tt>, but do note that some pixel formats (most notably YV12) has vertical chroma subsampling, and then the U/V planes may be of a different height than the primary plane.</li>
<li><b><tt>int EncodedWidth; int EncodedHeight</tt></b> - The original resolution of the frame (in pixels), as encoded in the compressed file, before any scaling was applied. Note that must not necessarily be the same for all frames in a stream.</li>
<li><b><tt>int EncodedPixelFormat</tt></b> - The original pixel format of the frame, as encoded in the compressed file.</li>
<li><b><tt>int ScaledWidth; int ScaledHeight;</tt></b> - The output resolution of the frame (in pixels), i.e. the resolution of what is actually stored in the <tt>Data</tt> field. Same as <tt>FFMS_VideoProperties->Width/Height</tt>, but unlike that struct, this one gets updated automatically when you call <tt>FFMS_GetFrame</tt>, so you don't have to call <tt>FFMS_GetVideoProperties</tt> all the time to see if someone changed the output format while you weren't looking.</li>
<li><b><tt>int ConvertedPixelFormat</tt></b> - The output pixel format of the frame, i.e. the pixel format of what is actually stored in the <tt>Data</tt> field.</li>
<li><b><tt>int KeyFrame</tt></b> - Nonzero if the frame is a keyframe, 0 otherwise.</li>
<li><b><tt>int RepeatPict</tt></b> - An integer repesenting the RFF flag for this frame; i.e. the frame shall be displayed for <tt>1+RepeatPict</tt> time units, where the time units are expressed in the special RFF timebase available in <tt>FFMS_VideoProperties->RFFDenominator</tt> and <tt>FFMS_VideoProperties->RFFNumerator</tt>. Note that if you actually end up using this, you need to ignore the usual timestamps (calculated via the <tt>FFMS_TrackTimeBase</tt> and the frame DTS) since they are fundamentally incompatible with RFF flags.</li>
<li><b><tt>int InterlacedFrame</tt></b> - Nonzero if the frame was coded as interlaced, zero otherwise.</li>
<li><b><tt>int TopFieldFirst</tt></b> - Nonzero if the frame has the top field first, zero if it has the bottom field first. Only relevant if <tt>InterlacedFrame</tt> is nonzero.</li>
<li><b><tt>char PictType</tt></b> - A single character denoting coding type (I/B/P etc) of the compressed frame. See the Constants and Preprocessor Definitions section for more information about what the different letters mean.</li>
</ul>

<h3>FFMS_TrackTimeBase</h3>
<pre>typedef struct {
	int64_t Num;
	int64_t Den;
} FFMS_TrackTimeBase;</pre>
<p>
A struct representing the basic time unit of a track, as a rational number where <tt>Num</tt> is the numerator and <tt>Den</tt> is the denominator. Note that while this rational number may occasionally turn out to be equal to 1/framerate for some CFR video tracks, it really has no relation whatsoever with the video framerate and you should definitely not assume anything framerate-related based on it.
</p>

<h3>FFMS_FrameInfo</h3>
<pre>typedef struct {
	int64_t PTS;
	int RepeatPict;
	int KeyFrame;
} FFMS_FrameInfo;</pre>
<p>A struct representing basic metadata about a given video frame. The fields are:</p>
<ul>
<li><b><tt>int64_t DTS</tt></b> - The decoding timestamp of the frame. To convert this to a timestamp in wallclock milliseconds, use the relation <tt>int64_t timestamp = (int64_t)((FFMS_FrameInfo-&gt;DTS * FFMS_TrackTimeBase-&gt;Num) / (double)FFMS_TrackTimeBase-&gt;Den)</tt>.</li>
<li><b><tt>int RepeatPict</tt></b> - RFF flag for the frame; same as in <tt>FFMS_Frame</tt>, see that structure for an explanation.</li>
<li><b><tt>int KeyFrame</tt></b> - Non-zero if the frame is a keyframe, zero otherwise.</li>
</ul>

<h3>FFMS_VideoProperties</h3>
<pre>typedef struct {
	int FPSDenominator;
	int FPSNumerator;
	int RFFDenominator;
	int RFFNumerator;
	int NumFrames;
	int SARNum;
	int SARDen;
	int CropTop;
	int CropBottom;
	int CropLeft;
	int CropRight;
	int TopFieldFirst;
	int ColorSpace;
	int ColorRange;
	double FirstTime;
	double LastTime;
} FFMS_VideoProperties;</pre>
<p>A struct containing metadata about a video track. The fields are:</p>
<ul>
<li><b><tt>int FPSDenominator; int FPSNumerator;</tt></b> - The nominal framerate of the track, as a rational number. For Matroska files, this number is based on the average frame duration of all frames, while for everything else it's based on the duration of the first frame. While it might seem tempting to use these values to extrapolate wallclock timestamps for each frame, you really shouldn't do that since it makes your code unable to handle variable framerate properly. The ugly reality is that these values are pretty much only useful for informational purposes; they are only somewhat reliable for antiquated containers like AVI. Normally they should never be used for practical purposes; generate individual frame timestamps from <tt>FFMS_FrameInfo-&gt;DTS</tt> instead.</li>
<li><b><tt>int RFFDenominator; int RFFNumerator;</tt></b> - The special RFF timebase, as a rational number. See <tt>RepeatPict</tt> in the <tt>FFMS_Frame</tt> documentation for more information.</li>
<li><b><tt>int NumFrames;</tt></b> - The number of frames in the video track.</li>
<li><b><tt>int SARNum; int SARDen;</tt></b> - The sample aspect ratio of the video frames, as a rational number where <tt>SARNum</tt> is the numerator and <tt>SARDen</tt> is the denominator. Note that this is a metadata setting that you are free to ignore, but if you want the proper display aspect ratio with anamorphic material, you should honor it. On the other hand, there are situations (like when encoding) where you should probably ignore it because the user expects it to be ignored.</li>
<li><b><tt>int CropTop; int CropBottom; int CropLeft; int CropRight;</tt></b> - The number of pixels in each direction you should crop the frame before displaying it. Note that like the SAR, this is a metadata setting and you are free to ignore it, but if you want things to display 100% correctly you should honor it.</li>
<li><b><tt>int TopFieldFirst</tt></b> - Nonzero if the stream has the top field first, zero if it has the bottom field first.</li>
<li><b><tt>int ColorSpace</tt></b> - Identifies the YUV color coefficients used in the stream. Same as in the MPEG-2 specs, see AVColorSpace in avcodec.h for more information.</li>
<li><b><tt>int ColorRange</tt></b> - Identifies the luma range of the stream. 0 means unspecified or unknown, 1 means TV range (16-235) and 2 means PC range (0-255).</li>
<li><b><tt>double FirstTime; double LastTime;</tt></b> - The first and last timestamp of the stream respectively, in milliseconds. Useful if you want to know if the stream has a delay, or for quickly determining its length in seconds.</li>
</ul>

<h3>FFMS_AudioProperties</h3>
<pre>typedef struct {
	int SampleFormat;
	int SampleRate;
	int BitsPerSample;
	int Channels;
	int64_t ChannelLayout;
	int64_t NumSamples;
	double FirstTime;
	double LastTime;
} FFMS_AudioProperties;</pre>
<p>A struct containing metadata about an audio track. The fields are:</p>
<ul>
<li><b><tt>int SampleFormat</tt></b> - An integer that represents the audio sample format. See <tt>FFMS_SampleFormat</tt> in the Constants and Preprocessor Definitions section.</li>
<li><b><tt>int SampleRate</tt></b> - The audio samplerate, in samples per second.</li>
<li><b><tt>int BitsPerSample</tt></b> - The number of bits per audio sample. Note that this signifies the number of bits actually used to <i>code</i> each sample, not the number of bits used to <i>store</i> each sample, and may hence be different from what the <tt>SampleFormat</tt> would imply. Figuring out which bytes are significant and which aren't is left as an exercise for the reader.</li>
<li><b><tt>int Channels</tt></b> - The number of audio channels.</li>
<li><b><tt>int64_t ChannelLayout</tt></b> - The channel layout of the audio stream. Constructed by binary OR'ing the relevant integers from <tt>FFMS_AudioChannel</tt> together, which means that if the audio has the channel <tt>FFMS_CH_EXAMPLE</tt>, the operation <tt>(ChannelOrder &amp; FFMS_CH_EXAMPLE)</tt> will evaluate to true. The samples are interleaved in the order the channels are listed in the <tt>FFMS_AudioChannel</tt> enum; see that part of the Constants and Preprocessor Definitions sections for more details.</li>
<li><b><tt>int64_t NumSamples</tt></b> - The number of samples in the audio track.</li>
<li><b><tt>double FirstTime; double LastTime;</tt></b> - The first and last timestamp of the stream respectively, in milliseconds. Useful if you want to know if the stream has a delay, or for quickly determining its length in seconds.</li>
</ul>


<h2>Constants and Preprocessor Definitions</h2>
<p>The following constants and preprocessor definititions defined in ffms.h are suitable for public usage.</p>

<h3>FFMS_Errors</h3>
<pre>enum FFMS_Errors {
	// No error
	FFMS_ERROR_SUCCESS = 0,

	// Main types - where the error occurred
	FFMS_ERROR_INDEX = 1,
	FFMS_ERROR_INDEXING,
	FFMS_ERROR_POSTPROCESSING,
	FFMS_ERROR_SCALING,
	FFMS_ERROR_DECODING,
	FFMS_ERROR_SEEKING,
	FFMS_ERROR_PARSER,
	FFMS_ERROR_TRACK,
	FFMS_ERROR_WAVE_WRITER,
	FFMS_ERROR_CANCELLED,

	// Subtypes - what caused the error
	FFMS_ERROR_UNKNOWN = 20,
	FFMS_ERROR_UNSUPPORTED,
	FFMS_ERROR_FILE_READ,
	FFMS_ERROR_FILE_WRITE,
	FFMS_ERROR_NO_FILE,
	FFMS_ERROR_VERSION,
	FFMS_ERROR_ALLOCATION_FAILED,
	FFMS_ERROR_INVALID_ARGUMENT,
	FFMS_ERROR_CODEC,
	FFMS_ERROR_NOT_AVAILABLE,
	FFMS_ERROR_FILE_MISMATCH,
	FFMS_ERROR_USER
};</pre>
<p>
Used to identify errors. Should be self-explanatory.
</p>

<h3>FFMS_Sources</h3>
<pre>enum FFMS_Sources {
	FFMS_SOURCE_LAVF		= 0x01,
	FFMS_SOURCE_MATROSKA	= 0x02,
	FFMS_SOURCE_HAALIMPEG	= 0x04,
	FFMS_SOURCE_HAALIOGG	= 0x08
};</pre>
<p>
Identifies source modules.
</p>
<ul>
<li><b><tt>FFMS_SOURCE_LAVF</tt></b> - libavformat (ffmpeg)</li>
<li><b><tt>FFMS_SOURCE_LAVF</tt></b> - Haali's BSD-licensed native Matroska parsing library</li>
<li><b><tt>FFMS_SOURCE_HAALIMPEG</tt></b> - Haali's closed-source DirectShow splitter (MPEG TS/PS)</li>
<li><b><tt>FFMS_SOURCE_HAALIOGG</tt></b> - Haali's closed-source DirectShow splitter (Ogg/OGM)</li>
</ul>

<h3>FFMS_CPUFeatures</h3>
<pre>enum FFMS_CPUFeatures {
	FFMS_CPU_CAPS_MMX       = 0x01,
	FFMS_CPU_CAPS_MMX2      = 0x02,
	FFMS_CPU_CAPS_3DNOW     = 0x04,
	FFMS_CPU_CAPS_ALTIVEC   = 0x08,
	FFMS_CPU_CAPS_BFIN      = 0x10
};</pre>
<p>
Used in <tt>FFMS_Init</tt> to indicate CPU instruction set capabilities. Should be self explanatory. For a lot of applications you can probably get away with simply hardcoding in <tt>FFMS_CPU_CAPS_MMX | FFMS_CPU_CAPS_MMX2</tt> in the call to <tt>FFMS_Init</tt>.
</p>

<h3>FFMS_SeekMode</h3>
<pre>enum FFMS_SeekMode {
	FFMS_SEEK_LINEAR_NO_RW  = -1,
	FFMS_SEEK_LINEAR        = 0,
	FFMS_SEEK_NORMAL        = 1,
	FFMS_SEEK_UNSAFE        = 2,
	FFMS_SEEK_AGGRESSIVE    = 3
};</pre>
<p>Used in <tt>FFMS_CreateVideoSource</tt> to control the way seeking is handled. Explanation of the values:</p>
<ul>
<li><b><tt>FFMS_SEEK_LINEAR_NO_RW</tt></b> - Linear access without rewind; i.e. will throw an error if each successive requested frame number isn't bigger than the last one. Only intended for opening images but might work on well with some obscure video format.</li>
<li><b><tt>FFMS_SEEK_LINEAR</tt></b> - Linear access (i.e. if you request frame <tt>n</tt> without having requested frames 0 to <tt>n-1</tt> in order first, all frames from 0 to <tt>n</tt> will have to be decoded before <tt>n</tt> can be delivered). The definition of slow, but should make some formats "usable".</li>
<li><b><tt>FFMS_SEEK_NORMAL</tt></b> - Safe normal. Bases seeking decisions on the keyframe positions reported by libavformat.</li>
<li><b><tt>FFMS_SEEK_UNSAFE</tt></b> - Unsafe normal. Same as <tt>FFMS_SEEK_NORMAL</tt> but no error will be thrown if the exact destination has to be guessed.</li>
<li><b><tt>FFMS_SEEK_AGGRESSIVE</tt></b> - Aggressive. Seeks in the forward direction even if no closer keyframe is known to exist. Only useful for testing and containers where libavformat doesn't report keyframes properly.</li>
</ul>

<h3>FFMS_IndexErrorHandling</h3>
<pre>enum FFMS_IndexErrorHandling {
	FFMS_IEH_ABORT = 0,
	FFMS_IEH_CLEAR_TRACK = 1,
	FFMS_IEH_STOP_TRACK = 2,
	FFMS_IEH_IGNORE = 3
};</pre>
<p>
Used by the indexing functions to control behavior when a decoding error is encountered.
</p>
<ul>
<li><b><tt>FFMS_IEH_ABORT</tt></b> - abort indexing and raise an error</li>
<li><b><tt>FFMS_IEH_CLEAR_TRACK</tt></b> - clear all indexing entries for the track (i.e. return a blank track)</li>
<li><b><tt>FFMS_IEH_STOP_TRACK</tt></b> - stop indexing but keep previous indexing entries (i.e. return a track that stops where the error occurred)</li>
<li><b><tt>FFMS_IEH_IGNORE</tt></b> - ignore the error and pretend it's raining</li>
</ul>

<h3>FFMS_TrackType</h3>
<pre>enum FFMS_TrackType {
	FFMS_TYPE_UNKNOWN = -1,
	FFMS_TYPE_VIDEO,
	FFMS_TYPE_AUDIO,
	FFMS_TYPE_DATA,
	FFMS_TYPE_SUBTITLE,
	FFMS_TYPE_ATTACHMENT
};</pre>
<p>
Used for determining the type of a given track. Note that there are currently no functions to handle any type of track other than <tt>FFMS_TYPE_VIDEO</tt> and <tt>FFMS_TYPE_AUDIO</tt>. See <tt>FFMS_GetTrackType</tt>, <tt>FFMS_GetFirstTrackOfType</tt> and their variants.
</p>

<h3>FFMS_SampleFormat</h3>
<pre>enum FFMS_SampleFormat {
    FFMS_FMT_U8 = 0,
    FFMS_FMT_S16,
    FFMS_FMT_S32,
    FFMS_FMT_FLT,
    FFMS_FMT_DBL
};</pre>
<p>Identifies various audio sample formats.</p>
<ul>
<li><b><tt>FFMS_FMT_U8</tt></b> - One 8-bit unsigned integer (<tt>uint8_t</tt>) per sample.</li>
<li><b><tt>FFMS_FMT_S16</tt></b> - One 16-bit signed integer (<tt>int16_t</tt>) per sample.</li>
<li><b><tt>FFMS_FMT_S32</tt></b> - One 32-bit signed integer (<tt>int32_t</tt>) per sample.</li>
<li><b><tt>FFMS_FMT_FLT</tt></b> - One 32-bit (single precision) floating point value (<tt>float_t</tt>) per sample.</li>
<li><b><tt>FFMS_FMT_DBL</tt></b> - One 64-bit (double precision) floating point value (<tt>double_t</tt>) per sample.</li>
</ul>

<h3>FFMS_AudioChannel</h3>
<pre>enum FFMS_AudioChannel {
	FFMS_CH_FRONT_LEFT              = 0x00000001,
	FFMS_CH_FRONT_RIGHT             = 0x00000002,
	FFMS_CH_FRONT_CENTER            = 0x00000004,
	FFMS_CH_LOW_FREQUENCY           = 0x00000008,
	FFMS_CH_BACK_LEFT               = 0x00000010,
	FFMS_CH_BACK_RIGHT              = 0x00000020,
	FFMS_CH_FRONT_LEFT_OF_CENTER    = 0x00000040,
	FFMS_CH_FRONT_RIGHT_OF_CENTER   = 0x00000080,
	FFMS_CH_BACK_CENTER             = 0x00000100,
	FFMS_CH_SIDE_LEFT               = 0x00000200,
	FFMS_CH_SIDE_RIGHT              = 0x00000400,
	FFMS_CH_TOP_CENTER              = 0x00000800,
	FFMS_CH_TOP_FRONT_LEFT          = 0x00001000,
	FFMS_CH_TOP_FRONT_CENTER        = 0x00002000,
	FFMS_CH_TOP_FRONT_RIGHT         = 0x00004000,
	FFMS_CH_TOP_BACK_LEFT           = 0x00008000,
	FFMS_CH_TOP_BACK_CENTER         = 0x00010000,
	FFMS_CH_TOP_BACK_RIGHT          = 0x00020000,
	FFMS_CH_STEREO_LEFT             = 0x20000000,
	FFMS_CH_STEREO_RIGHT            = 0x40000000
};</pre>
<p>
Describes various audio channel configurations. The names should be self-explanatory. The actual order if FFmpeg dictated and may vary.
</p>

<h3>FFMS_Resizers</h3>
<pre>enum FFMS_Resizers {
    FFMS_RESIZER_FAST_BILINEAR  = 0x01,
    FFMS_RESIZER_BILINEAR       = 0x02,
    FFMS_RESIZER_BICUBIC        = 0x04,
    FFMS_RESIZER_X              = 0x08,
    FFMS_RESIZER_POINT          = 0x10,
    FFMS_RESIZER_AREA           = 0x20,
    FFMS_RESIZER_BICUBLIN       = 0x40,
    FFMS_RESIZER_GAUSS          = 0x80,
    FFMS_RESIZER_SINC           = 0x100,
    FFMS_RESIZER_LANCZOS        = 0x200,
    FFMS_RESIZER_SPLINE         = 0x400
};</pre>
<p>
Describes various image resizing algorithms, as used in the arguments to <tt>FFMS_SetOutputFormatV</tt>. The names should be self-explanatory.
</p>


<h3>FFMS_CC</h3>
<pre>#ifdef _WIN32
#	define FFMS_CC __stdcall
#else
#	define FFMS_CC
#endif
</pre>
<p>
The calling convention used by FFMS2 API functions and callbacks. Defined to <tt>__stdcall</tt> if <tt>_WIN32</tt> is defined. Otherwise defined, but not used.
</p>


<h3>Picture types</h3>
<p>As stored in <tt>FFMS_Frame->PictType</tt>:</p>
<pre>I: Intra
P: Predicted
B: Bi-dir predicted
S: S(GMC)-VOP MPEG4
i: Switching Intra
p: Switching Predicted
b: FF_BI_TYPE (no good explanation available)
?: Unknown</pre>


<h2>Audio Filename Format Strings</h2>
<p>The following variables can be used:</p>
<ul>
<li><tt>%sourcefile%</tt> - same as the source file name, i.e. the file the audio is decoded from</li>
<li><tt>%trackn%</tt> - the track number</li>
<li><tt>%trackzn%</tt> - the track number zero padded to 2 digits</li>
<li><tt>%samplerate%</tt> - the audio sample rate</li>
<li><tt>%channels%</tt> - number of audio channels</li>
<li><tt>%bps%</tt> - bits per sample</li>
<li><tt>%delay%</tt> - delay, or more exactly the first timestamp encountered in the audio stream</li>
</ul>
<p>
Example string: <tt>%sourcefile%_track%trackzn%.w64</tt>
</p>


<h2>PP string format</h2>
<pre>
Available postprocessing filters:
Filters                        Options
short  long name       short   long option     Description
*      *               a       autoq           CPU power dependent enabler
                       c       chrom           chrominance filtering enabled
                       y       nochrom         chrominance filtering disabled
                       n       noluma          luma filtering disabled
hb     hdeblock        (2 threshold)           horizontal deblocking filter
       1. difference factor: default=32, higher -&gt; more deblocking
       2. flatness threshold: default=39, lower -&gt; more deblocking
                       the h &amp; v deblocking filters share these
                       so you can't set different thresholds for h / v
vb     vdeblock        (2 threshold)           vertical deblocking filter
ha     hadeblock       (2 threshold)           horizontal deblocking filter
va     vadeblock       (2 threshold)           vertical deblocking filter
h1     x1hdeblock                              experimental h deblock filter 1
v1     x1vdeblock                              experimental v deblock filter 1
dr     dering                                  deringing filter
al     autolevels                              automatic brightness / contrast
f      fullyrange                              stretch luminance to (0..255)
lb     linblenddeint                           linear blend deinterlacer
li     linipoldeint                            linear interpolating deinterlace
ci     cubicipoldeint                          cubic interpolating deinterlacer
md     mediandeint                             median deinterlacer
fd     ffmpegdeint                             ffmpeg deinterlacer
l5     lowpass5                                FIR lowpass deinterlacer
de     default                                 hb:a,vb:a,dr:a
fa     fast                                    h1:a,v1:a,dr:a
ac                                             ha:a:128:7,va:a,dr:a
tn     tmpnoise        (3 threshold)           temporal noise reducer
                     1. &lt;= 2. &lt;= 3.            larger -&gt; stronger filtering
fq     forceQuant      &lt;quantizer&gt;             force quantizer
Usage:
&lt;filterName&gt;[:&lt;option&gt;[:&lt;option&gt;...]][[,|/][-]&lt;filterName&gt;[:&lt;option&gt;...]]...
long form example:
vdeblock:autoq/hdeblock:autoq/linblenddeint    default,-vdeblock
short form example:
vb:a/hb:a/lb                                   de,-vb
more examples:
tn:64:128:256
</pre>

</div>

</body>
</html>
